#pragma once
#include "Epoll.hpp"
#include "Common.hpp"
#include "Connection.hpp"
#include <unordered_map>
#include <memory>

class Reactor
{
public:
    static const int _revs_num = 128;

    Reactor()
        : _epoller_ptr(std::make_shared<Epoller>()), _isrunning(false)
    {
    }
    // 向Epoll模型中添加connection
    void AddConnection(std::shared_ptr<Connection> conn)
    {
        int sockfd = conn->GetFd();
        uint32_t events = conn->GetEvents();
        _epoller_ptr->AddEvent(sockfd, events);

        _connections[sockfd] = conn;
        LOG(LogLevel::DBUGER)<<"成功加入hash表,fd:"<<sockfd;
    }
    void Dispatcher(int rnum)
    {
        for (int i = 0; i < rnum; i++)
        {
            int sockfd = _revs[i].data.fd;
            uint32_t events = _revs[i].events;
            // 处理读事件
            if (events & EPOLLIN)
            {
                _connections[sockfd]->Recver();
            }
            // 处理写事件
            if (events & EPOLLOUT)
            {
                _connections[sockfd]->Send();
            }
        }
    }

    void Start()
    {
        while (true)
        {
            // 阻塞等待

            int rnum = _epoller_ptr->Wait(_revs, _revs_num, -1);

            // 等完就派发事务
            Dispatcher(rnum);
        }
    }
    void SetConn(std::shared_ptr<Connection>& conn)
    {
        _connections[conn->GetFd()]=conn;
    }

public:
    // Epoll模型
    std::shared_ptr<Epoller> _epoller_ptr;
    // 管理所有的链接，键值是文件描述符
    std::unordered_map<int, std::shared_ptr<Connection>> _connections;

    // 是否启动
    bool _isrunning;

    // 就绪事件数组
    struct epoll_event _revs[_revs_num];
};